<?php

/**
 * uniBoard Paginator
 *
 * Light and fast forum solution for web 2.0-like communities.
 *
 * @package		uniBoard
 * @author		Rafał Pitoń
 * @license		http://www.gnu.org/licenses/gpl-3.0.html
 * @since		Version 0.1
 * 
 * ------------------------------------------------------------------------
 * 
 * $Date: 2010-09-20 21:23:27 +0000 (Mon, 20 Sep 2010) $
 * $Revision: 64 $
 * $Author: rafio.xudb@gmail.com $
 */

// ------------------------------------------------------------------------

class class_paginator{
		
	/**
	 * Main class pointer
	 *
	 * @var object
	 */
	
	private $appCore			= NULL;
	
	/**
	 * Link (we use "%s" to identify place in link we will replace with user-specified page)
	 *
	 * @var string
	 */
	
	private $link_base 			= '';
			
	/**
	 * Items Number
	 *
	 * @var integer
	 */
	
	private $items_num 			= 0;
		
	/**
	 * Items per Page
	 *
	 * @var integer
	 */
	
	private $page_size			= 0;
		
	/**
	 * Pages Total
	 *
	 * @var integer
	 */
	
	private $pages_total		= 0;
	
	/**
	 * Current Position
	 *
	 * @var integer
	 */
	
	private $current_pos 		= 0;
	
	/**
	 * Template
	 *
	 * @var object
	 */
	
	private $template	 		= 0;
	
	/**
	 * Any JS code displayed?
	 *
	 * @var bool
	 */
	
	static private $js_drawn 	= false;
	
	// ------------------------------------------------------------------------

	/**
	 * Create Paginator
	 *
	 * @param object $appCore
	 * @param string $link_base
	 * @param integer $items_num
	 * @param integer $page_size
	 */
	
	function __construct( $appCore, $link_base = '', $items_num = 0, $page_size = 1){
		
		// Store appCore pointer
		$this -> appCore = $appCore;
		
		// Store Link base and entire stuff
		$this -> link_base = $link_base;
		$this -> items_num = $items_num;
		$this -> page_size = $page_size;
		
		// Pages number
		$this -> pages_total = ceil( $this -> items_num / $this -> page_size) - 1;
		
		// Get Current pos
		$this -> current_pos = (integer) $appCore -> _REQ( 'st');
		
		// Is Pos outside range?
		if ( $this -> current_pos < 0)
		{
			// Set Position to ZERO
			$this -> current_pos = 0;
		}
			
		// Position is too big?
		if ( $this -> current_pos > $this -> items_num)
		{
			// Make current pos equal to max step
			$this -> current_pos = $this -> pages_total * $this -> page_size;
		}

		// Create template
		$this -> template = new tpl_paginator( $appCore);
	
		// Draw JS?
		if ( !self::$js_drawn)
		{
			// JS Drawn already
			self::$js_drawn = true;
			
			// Draw Paginator code
			$appCore -> output -> js_code .= $this -> template -> tpl_pager_js( array(
				'page_base_url' => str_replace( '&amp;', '&', $link_base),
				'pages_total' => $this -> pages_total + 1,
				'page_size' => $page_size
			));
		}
		
	}
	
	// ------------------------------------------------------------------------

	/**
	 * Returns actual position for MySQL
	 *
	 * @return integer
	 */
	
	function getPosition(){
		
		//return actual pos
		return $this -> current_pos;
		
	}
	
	// ------------------------------------------------------------------------

	/**
	 * Draws whole Paginator thingie
	 *
	 * @return string
	 */
	
	function draw(){
	
		// Template vars
		$tpl_vars = array(
			'pages_list' => '',
			'pages_total' => $this -> pages_total
		);
		
		// Pages number
		$pages_number = ceil( $this -> items_num / $this -> page_size);
		
		// Actual page?
		if ( $this -> current_pos > 0)
		{
			// Actual page number
			$tpl_vars['page_current'] = $this -> current_pos / $this -> page_size;
		}
		else
		{
			// Actual page is first page
			$tpl_vars['page_current'] = 0;	
		}
		
		// Drawed page
		$drawed_page = 0;
		
		// Draw pages?
		if ( $pages_number > 0)
		{
			// Iterate pages while we hit final page. We will be jumping from time to time, thats why loop will be handled by while, not for
			while ( $drawed_page < $pages_number)
			{
				// Are we on Current page?
				if ( $drawed_page == $tpl_vars['page_current'])
				{
					$tpl_vars['pages_list'] .= $this -> template -> tpl_page_active( array( 'page_link' => sprintf( $this -> link_base, ( $drawed_page * $this -> page_size)), 'page_number' => ($drawed_page + 1)));
				}
				else
				{
					$tpl_vars['pages_list'] .= $this -> template -> tpl_page( array( 'page_link' => sprintf( $this -> link_base, ( $drawed_page * $this -> page_size)), 'page_number' => ($drawed_page + 1)));
				}
				
				// Jump to last page?
				if ( $drawed_page + 2 < $tpl_vars['page_current'])
				{
					$drawed_page = $tpl_vars['page_current'] - 2;
				}
				else if ( $tpl_vars['page_current'] + 2 == $drawed_page)
				{
					if ( $drawed_page + 2 <= $pages_number)
					{
						$tpl_vars['pages_list'] .= $this -> template -> tpl_page( array( 'page_link' => sprintf( $this -> link_base, (($pages_number - 1) * $this -> page_size)), 'page_number' => $pages_number));
					}
						
					// Break Loop
					break;
				}
				else
				{
					// Increase page number
					$drawed_page ++;
				}
			}
		}
		else
		{
			// Draw only first page
			$tpl_vars['pages_list'] .= $this -> template -> tpl_page_active( array( 'page_link' => sprintf( $this -> link_base, 0), 'page_number' => 1));	
		}
		
		// Fix stats
		$tpl_vars['page_current'] ++;
		$tpl_vars['pages_total'] = $pages_number;
		
		// Return drawed steps
		return $this -> template -> tpl_paginator_body( $tpl_vars);
		
	}
	
	// ------------------------------------------------------------------------

	/**
	 * Compact Page Selector
	 *
	 * @return string
	 */
	
	function drawCompact(){
		
		//pages number
		$pages_num = ceil( $this -> items_num / $this -> jump_size);
		
		//fix it
		if ( $pages_num < 1)
			$pages_num = 1;

		//tpl vars
		$tpl_vars = array(
			'pages_number' => $pages_num,
			'pages_list' => '',
			'last_page_number' => $pages_num,
			'last_page_link' => $this -> drawLink( $this -> jump_size * ( $pages_num - 1))
		);
		
		//draw pages
		for ( $i = 1; $i <= ( $pages_num > 3 ? 3 : $pages_num); $i++ ) {
			
			//draw page
			$tpl_vars['pages_list'] .= $templates -> template_tiny_paginator_page( array( 'page_number' => $i, 'page_link' => $this -> drawLink( $this -> jump_size * ( $i - 1))));
	
		}
		
		//draw JS?
		if ( !$this -> tiny_pager_js){
			
			//block from multipling our JS
			$this -> tiny_pager_js = true;
			
			//set JS
			$unisolutions -> controller -> addToScripts( $templates -> template_tiny_paginator_js( array(
				'base_url' => str_replace( '&amp;', '&', $this -> link_base).'&'.$this -> link_page_var.'=',
				'pages_number' => $pages_num,
				'jump_size' => $this -> jump_size
			)));
			
		}
		
		//draw template
		return $templates -> template_tiny_paginator_body( $tpl_vars);
		
	}
	
}